home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / cool / cool.lha / lice / mkdepend / include.c < prev    next >
C/C++ Source or Header  |  1991-09-04  |  7KB  |  296 lines

  1. /*
  2. //
  3. // Copyright (C) 1991 Texas Instruments Incorporated.
  4. //
  5. // Permission is granted to any individual or institution to use, copy, modify,
  6. // and distribute this software, provided that this complete copyright and
  7. // permission notice is maintained, intact, in all copies and supporting
  8. // documentation.
  9. //
  10. // Texas Instruments Incorporated provides this software "as is" without
  11. // express or implied warranty.
  12. //
  13.  * $XConsortium: include.c,v 1.7 88/11/08 12:19:55 jim Exp $
  14.  */
  15. #include "def.h"
  16.  
  17. extern struct    inclist    inclist[ MAXFILES ],
  18.             *inclistp;
  19. extern char    *includedirs[ ];
  20. extern char    *notdotdot[ ];
  21. extern boolean show_where_not;
  22. extern char path_sep;
  23.  
  24. struct inclist *inc_path(file, include, dot)
  25.     register char    *file,
  26.             *include;
  27.     boolean    dot;
  28. {
  29.     static char    path[ BUFSIZ ];
  30.     register char        **pp, *p;
  31.     register struct inclist    *ip;
  32.     struct stat    st;
  33.     boolean    found = FALSE;
  34.  
  35.     /*
  36.      * Check all previously found include files for a path that
  37.      * has already been expanded.
  38.      */
  39.     for (ip = inclist; ip->i_file; ip++)
  40.         if ((strcmp(ip->i_incstring, include) == 0) && !ip->i_included_sym)
  41.         {
  42.         found = TRUE;
  43.         break;
  44.         }
  45.  
  46.     /*
  47.      * If the path was surrounded by "", then check the absolute
  48.      * path provided.
  49.      */
  50.     if (!found && dot) {
  51.         if (stat(include, &st) == 0) {
  52.             ip = newinclude(include, include);
  53.             found = TRUE;
  54.         }
  55.         else if (show_where_not)
  56.             do_log("\tnot in %s\n", include);
  57.     }
  58.  
  59.     /*
  60.      * See if this include file is in the directory of the
  61.      * file being compiled.
  62.      */
  63.     if (!found) {
  64.         for (p=file+strlen(file); p>file; p--)
  65.             if (*p == path_sep)
  66.                 break;
  67.         if (p == file)
  68.             strcpy(path, include);
  69.         else {
  70.             strncpy(path, file, (p-file) + 1);
  71.             path[ (p-file) + 1 ] = '\0';
  72.             strcpy(path + (p-file) + 1, include);
  73.         }
  74.         remove_dotdot(path);
  75.         if (stat(path, &st) == 0) {
  76.             ip = newinclude(path, include);
  77.             found = TRUE;
  78.         }
  79.         else if (show_where_not)
  80.             do_log("\tnot in %s\n", path);
  81.     }
  82.  
  83.     /*
  84.      * Check the include directories specified. (standard include dir
  85.      * should be at the end.)
  86.      */
  87.     if (!found)
  88.         for (pp = includedirs; *pp; pp++) {
  89. #ifdef VMS
  90.             sprintf(path, "%s%s", *pp, include);
  91. #else
  92. #ifdef os2
  93.             sprintf(path, "%s\\%s", *pp, include);
  94. #else
  95.             sprintf(path, "%s/%s", *pp, include);
  96. #endif
  97. #endif
  98.             remove_dotdot(path);
  99.             if (stat(path, &st) == 0) {
  100.                 ip = newinclude(path, include);
  101.                 found = TRUE;
  102.                 break;
  103.             }
  104.             else if (show_where_not)
  105.                 do_log("\tnot in %s\n", path);
  106.         }
  107.  
  108.     if (!found) {
  109.         /*
  110.          * If we've announced where it's not include it anyway so
  111.          * it gets on the dependency list.
  112.          */
  113.         if (show_where_not)
  114.             ip = newinclude(include, include);
  115.         else
  116.             ip = NULL;
  117.     }
  118.     return(ip);
  119. }
  120.  
  121. /*
  122.  * Ocaisionally, pathnames are created that look like ../x/../y
  123.  * Any of the 'x/..' sequences within the name can be eliminated.
  124.  * (but only if 'x' is not a symbolic link!!)
  125.  */
  126. remove_dotdot(path)
  127.     char    *path;
  128. {
  129.     register char    *end, *from, *to, **cp;
  130.     char        *components[ MAXFILES ],
  131.             newpath[ BUFSIZ ];
  132.     boolean        component_copied;
  133.  
  134.     /*
  135.      * slice path up into components.
  136.      */
  137.     to = newpath;
  138.     if (*path == path_sep)
  139.         *to++ = path_sep;
  140.     *to = '\0';
  141.     cp = components;
  142.     for (from=end=path; *end; end++)
  143.         if (*end == path_sep) {
  144.             while (*end == path_sep)
  145.                 *end++ = '\0';
  146.             if (*from)
  147.                 *cp++ = from;
  148.             from = end;
  149.         }
  150.     *cp++ = from;
  151.     *cp = NULL;
  152.  
  153.     /*
  154.      * Now copy the path, removing all 'x/..' components.
  155.      */
  156.     cp = components;
  157.     component_copied = FALSE;
  158.     while(*cp) {
  159.         if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))) {
  160.             if (issymbolic(newpath, *cp))
  161.                 goto dont_remove;
  162.             cp++;
  163.         } else {
  164.         dont_remove:
  165.             if (component_copied)
  166.                 *to++ = path_sep;
  167.             component_copied = TRUE;
  168.             for (from = *cp; *from; )
  169.                 *to++ = *from++;
  170.             *to = '\0';
  171.         }
  172.         cp++;
  173.     }
  174.     *to++ = '\0';
  175.  
  176.     /*
  177.      * copy the reconstituted path back to our pointer.
  178.      */
  179.     strcpy(path, newpath);
  180. }
  181.  
  182. isdot(p)
  183.     register char    *p;
  184. {
  185.     if(p && *p++ == '.' && *p++ == '\0')
  186.         return(TRUE);
  187.     return(FALSE);
  188. }
  189.  
  190. isdotdot(p)
  191.     register char    *p;
  192. {
  193.     if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
  194.         return(TRUE);
  195.     return(FALSE);
  196. }
  197.  
  198. issymbolic(dir, component)
  199.     register char    *dir, *component;
  200. {
  201. #ifdef S_IFLNK
  202.     struct stat    st;
  203.     char    buf[ BUFSIZ ], **pp;
  204.  
  205.     sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
  206.     for (pp=notdotdot; *pp; pp++)
  207.         if (strcmp(*pp, buf) == 0)
  208.             return (TRUE);
  209.     if (lstat(buf, &st) == 0
  210.     && (st.st_mode & S_IFMT) == S_IFLNK) {
  211.         *pp++ = copy(buf);
  212.         if (pp >= ¬dotdot[ MAXDIRS ])
  213.             log_fatal("out of .. dirs, increase MAXDIRS\n");
  214.         return(TRUE);
  215.     }
  216. #endif
  217.     return(FALSE);
  218. }
  219.  
  220. /*
  221.  * Add an include file to the list of those included by 'file'.
  222.  */
  223. struct inclist *newinclude(newfile, incstring)
  224.     register char    *newfile, *incstring;
  225. {
  226.     register struct inclist    *ip;
  227.  
  228.     /*
  229.      * First, put this file on the global list of include files.
  230.      */
  231.     ip = inclistp++;
  232.     if (inclistp == inclist + MAXFILES - 1)
  233.         log_fatal("out of space: increase MAXFILES\n");
  234.     ip->i_file = copy(newfile);
  235.     ip->i_included_sym = FALSE;
  236.     if (incstring == NULL)
  237.         ip->i_incstring = ip->i_file;
  238.     else
  239.         ip->i_incstring = copy(incstring);
  240.  
  241.     return(ip);
  242. }
  243.  
  244. void
  245. included_by(ip, newfile)
  246.     register struct inclist    *ip, *newfile;
  247. {
  248.     register i;
  249.  
  250.     if (ip == NULL)
  251.         return;
  252.     /*
  253.      * Put this include file (newfile) on the list of files included
  254.      * by 'file'.  If 'file' is NULL, then it is not an include
  255.      * file itself (i.e. was probably mentioned on the command line).
  256.      * If it is already on the list, don't stick it on again.
  257.      */
  258.     if (ip->i_list == NULL)
  259.         ip->i_list = (struct inclist **)
  260.             malloc(sizeof(struct inclist *) * ++ip->i_listlen);
  261.     else {
  262.         for (i=0; i<ip->i_listlen; i++)
  263.             if (ip->i_list[ i ] == newfile) {
  264.                 if (!ip->i_included_sym)
  265.                 {
  266.                 /* only bitch if ip has */
  267.                 /* no #include SYMBOL lines  */
  268.                 
  269. /**
  270.  ** The log messages for multiply included files seems inappropriate now that
  271.  ** mkdepend generates dependencies for .[hcC] files instead of .o files. Thus
  272.  ** I'm commenting this stuff out for now -- MBN
  273.  **
  274.  **                log("%s includes %s more than once!\n",
  275.  **                    ip->i_file, newfile->i_file);
  276.  **                log("Already have\n");
  277.  **                for (i=0; i<ip->i_listlen; i++)
  278.  **                    log("\t%s\n", ip->i_list[i]->i_file);
  279.  **/                }
  280.                 return;
  281.             }
  282.         ip->i_list = (struct inclist **) realloc(ip->i_list,
  283.             sizeof(struct inclist *) * ++ip->i_listlen);
  284.     }
  285.     ip->i_list[ ip->i_listlen-1 ] = newfile;
  286. }
  287.  
  288. inc_clean ()
  289. {
  290.     register struct inclist *ip;
  291.  
  292.     for (ip = inclist; ip < inclistp; ip++) {
  293.         ip->i_marked = FALSE;
  294.     }
  295. }
  296.